package ink.tiptop.service.impl;

import com.trilead.ssh2.Connection;
import ink.tiptop.dto.req.RestartServiceBean;
import ink.tiptop.persist.domain.bo.JarInfo;
import ink.tiptop.persist.domain.bo.UploadJarsDto;
import ink.tiptop.persist.domain.bo.UploadJarsResultDto;
import ink.tiptop.persist.domain.bo.LocalViewDto;
import ink.tiptop.persist.domain.entity.ZjfBaseServerInfoEntity;
import ink.tiptop.persist.domain.entity.ZjfServiceRemoteViewEntity;
import ink.tiptop.dto.resp.upload.UploadInfo;
import ink.tiptop.service.RestartService;
import ink.tiptop.service.UploadService;
import ink.tiptop.service.ZjfBaseServerInfoService;
import ink.tiptop.service.ZjfServiceRemoteViewService;
import ink.tiptop.utils.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ink.tiptop.utils.JSON;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ink.tiptop.zjf
 * @Title: boot-server-eureka
 * @Package ink.tiptop.service.impl
 * @Description: 上传服务实现
 * @date 2020-08-01 21:44
 */
@Service("uploadService")
@Slf4j
public class UploadServiceImpl implements UploadService {
//    @Autowired
//    private ZjfModuleLocalViewService moduleLocalViewService;

    @Autowired
    private ZjfServiceRemoteViewService serviceRemoteViewService;

    @Autowired
    private ZjfBaseServerInfoService baseServerInfoService;

    @Autowired
    private RestartService restartService;

    @Override
    public UploadJarsResultDto uploadJars(UploadJarsDto dto) {
        log.info("准备上传jar包入参:{}", JSON.toJSONString(dto));
        // 1.获取远程视图的信息
        List<JarInfo> jarInfoList = dto.getJarInfoList();

        List<ZjfServiceRemoteViewEntity> viewEntityList = null;
        final Integer serverId = dto.getServerId();
        // 返回给前端,需要重启的应用
        List<UploadInfo> resultList = new ArrayList<>();
        // 先清除一次缓存中的重启列表,防止数据重复
        restartService.clearRestartList();
        ZjfBaseServerInfoEntity baseServerInfoEntity = baseServerInfoService.queryById(serverId);
        for (JarInfo jarInfo : jarInfoList) {
            // 2. 根据localId+serverId能找到一个唯一的远程视图信息
            viewEntityList = serviceRemoteViewService.getByLocalView(new LocalViewDto(jarInfo.getId(), serverId,jarInfo.getUser(),jarInfo.getVersion()));
            if (viewEntityList == null || viewEntityList.isEmpty()) {
                log.info("没有找到当前jar包所属的服务视图,user:{},version:{},moduleId:{},serverId:{}",
                        jarInfo.getUser(),jarInfo.getVersion(),jarInfo.getId(),serverId );
                continue;
            }
            // 3. 根据远程视图配置找到对应的服务器信息
            // 这里意思就是 本地一个jar包 可能被 多个服务依赖了
            for (ZjfServiceRemoteViewEntity viewEntity : viewEntityList) {
                if (baseServerInfoEntity == null) {
                    log.error("远程视图:{},uploadJars没有找到服务器信息", viewEntity.getName());
                    continue;
                }
                boolean succeed = this.upload(jarInfo, viewEntity, baseServerInfoEntity);
                if (succeed) {
                    RestartServiceBean restartServiceBean = restartService.saveRestartServiceListToCache(viewEntity, baseServerInfoEntity);
                    UploadInfo uploadInfo  = new UploadInfo();
                    BeanUtils.copyProperties(restartServiceBean, uploadInfo);
                    resultList.add(uploadInfo);
                }
            }
        }
        log.info("上传文件到远程服务器:{},结束", baseServerInfoEntity.getName());
        return new UploadJarsResultDto(true).list(resultList);
    }

    private boolean upload(JarInfo jarInfo, ZjfServiceRemoteViewEntity viewEntity, ZjfBaseServerInfoEntity baseServerInfoEntity) {
        Connection connection = null;
        try {
            connection = baseServerInfoService.getConnection(baseServerInfoEntity);
        } catch (IOException e) {
            log.error("获取远程connect失败");
            log.error(e.getMessage(), e);
            return false;
        }
        // 1.获取本地jar包
        String localJarPath = jarInfo.getParent() + File.separator + jarInfo.getName() + jarInfo.getOutputTarget() + jarInfo.getOutputJar();
        // 2.获取远程路径
        String remoteLib = viewEntity.getParent() + "/" + viewEntity.getName() + viewEntity.getLib();
//        String binRestart = viewEntity.getParent() + "/" + viewEntity.getName() + viewEntity.getBinStart();
        // 3.发送
        boolean success = FileUtils.uploadFileToSftp(connection, localJarPath, remoteLib);
        log.info("发送文件{},到{}{}", localJarPath, remoteLib, success ? "成功" : "失败");
        return success;
    }
}
